package com.yxx.controller.notify;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.yxx.medicinecommon.properties.WeChatProperties;
import com.yxx.service.OrderService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;


/**
 * @author yuxiangxun
 * @date 2024/9/27
 * @apiNote
 */
@RestController
@RequestMapping("/notify")
@Slf4j
@Api(tags = "支付回调")
public class PayNotifyController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private WeChatProperties weChatProperties;

    /**
     * 支付成功回调
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/paySuccess")
    public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
            //读取数据
        String data = readData(request);
        log.info("支付成功回调：{}",data);

        //数据解密
        String decryptData = decryptData(data);
        log.info("解密后的文本内容：{}",decryptData);

        JSONObject decryptData_Json = JSON.parseObject(decryptData);
        //单家平台订单号
        String outTradeNo = decryptData_Json.getString("out_trade_no");
        //微信支付交易号
        String transactionId = decryptData_Json.getString("transaction_id");

        log.info("商家平台订单号：{}",outTradeNo);
        log.info("微信支付交易号：{}",transactionId);

        //修改订单状态，来单提醒
        orderService.paySuccess(outTradeNo);

        //给微信响应
        responseToWeiXin(response);
    }

    /**
     * 读取数据
     * @param request
     * @return
     * @throws Exception
     */
    public String readData(HttpServletRequest request) throws Exception{
        BufferedReader reader = null;
        try {
            reader = request.getReader();
            StringBuffer result = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    /**
     * 数据解密
     * @param body body 传入的 JSON 字符串
     * @return 解密后的明文
     * @throws Exception Exception 如果解密过程中发生异常
     */
    private String decryptData(String body) throws Exception {
        try {
            // 解析传入的 JSON 字符串
            JSONObject resultObject = JSON.parseObject(body);
            if (resultObject == null) {
                throw new IllegalArgumentException("Invalid JSON body");
            }
            // 获取 JSON 中的 "resource" 对象
            JSONObject resource = resultObject.getJSONObject("resource");
            if (resource == null) {
                throw new IllegalArgumentException("Missing 'resource' in JSON body");
            }

            // 从 "resource" 对象中提取密文、随机数和关联数据
            String ciphertext = resource.getString("ciphertext");
            String nonce = resource.getString("nonce");
            String associatedData = resource.getString("associated_data");

            // 检查密文、随机数和关联数据是否为空
            if (ciphertext == null || nonce == null || associatedData == null) {
                throw new IllegalArgumentException("Missing required fields in 'resource'");
            }

            // 创建 AesUtil 实例，传入 API V3 密钥
            AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8));
            // 密文解密
            String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
                    nonce.getBytes(StandardCharsets.UTF_8),
                    ciphertext);

            // 返回解密后的明文
            return plainText;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 响应微信服务器
     * @param response HttpServletResponse 对象
     * @throws Exception 如果响应过程中发生异常
     */
    private void responseToWeiXin(HttpServletResponse response) throws Exception{
        try{
            // 设置 HTTP 状态码为 200
            response.setStatus(200);
            //创建一个 HashMap 对象，存储响应数据
            HashMap<Object,Object> map = new HashMap<>();
            map.put("code","SUCCESS");
            map.put("message","SUCCESS");
            // 设置响应头，指定内容类型为 JSON
            response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
            // 将 HashMap 转换为 JSON 字符串，并写入响应输出流
            response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8));
            // 刷新缓冲区，确保数据立即发送
            response.flushBuffer();
        }catch (Exception e){
            //记录日志
            e.printStackTrace();
            throw e;
        }
    }
}
